Took me 4 hours but finally figured it out. As per the code below, function "fA()" has duplicate parameters, one before function "B()" (print "1st") and one after (print "2nd"). B() calls fA(). The main program calls fA then B. The 2nd duplicate prints first, but then I get an exception at the call in B. I notice if I forward reference fA() before B() (at line 3) then it works fine, thye 2nd duplicate is always called. I could not get the first duplicate to run correctly.
void fA() { print "In fA() 1st\n" }
// void fA(void) // Forward Reference; Comment this line in and out
void B() { fA() }
void fA() { print "In fA() 2nd\n"
}
//void fA(void) // Comment this line in and out
// Call functions:
fA()
B()
llandale - Thu Jun 30 16:14:08 EDT 2011 |
Re: Duplicate Functions
That is not normal, but I noticed the same. A forward reference before and after the call will crash DOORS with an exception. I guess forward references are not properly implemented. If utterly needed, you could replace the forward declarations by a callback proxy like below. Nice thing about that is, you can change the function at runtime ...
// instead of forward declaring func() use a virtual function
int adFunc = 0;
void call_func_proxy( void cb(int), int x ) { cb(x) }
void set_func (void cb(int) ) { adFunc = (addr_ cb) int }
void func (int x) { if (adFunc != 0) call_func_proxy(addr_ adFunc, x) }
// that function uses the not yet declared func() ...
void myLibraryFunction () { func 10 }
// declare the func we want to use late
void theRealFunc (int var) {
print "This is the implementation of func that I would like to use:" var "\n"
}
// set it as the function we want to use now. May want to change that later.
set_func(theRealFunc)
myLibraryFunction ()
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Duplicate Functions Complied languages should either flag that as an error or print "2nd" both times, depending on how lenient they are about redefinitions. Interpreted languages should print "2nd" both times. I'm a burgeoning Ruby nerd in my off time, and the code below prints "2" both times.
#!/usr/bin/ruby1.9.1
def funcA
puts("1")
end
def funcB
funcA()
end
def funcA
puts("2")
end
funcA()
funcB()
|
Re: Duplicate Functions SystemAdmin - Wed Jul 06 10:15:05 EDT 2011 Complied languages should either flag that as an error or print "2nd" both times, depending on how lenient they are about redefinitions. Interpreted languages should print "2nd" both times. I'm a burgeoning Ruby nerd in my off time, and the code below prints "2" both times.
#!/usr/bin/ruby1.9.1
def funcA
puts("1")
end
def funcB
funcA()
end
def funcA
puts("2")
end
funcA()
funcB()
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Duplicate Functions SystemAdmin - Wed Jul 06 10:15:05 EDT 2011 Complied languages should either flag that as an error or print "2nd" both times, depending on how lenient they are about redefinitions. Interpreted languages should print "2nd" both times. I'm a burgeoning Ruby nerd in my off time, and the code below prints "2" both times.
#!/usr/bin/ruby1.9.1
def funcA
puts("1")
end
def funcB
funcA()
end
def funcA
puts("2")
end
funcA()
funcB()
Seems to me we did this years ago (with punch cards):
int iValue = 0
void ModIVal() {modify iValue}
int GetIVal() { return iValue}
int iValue = 0 // dummy variable to protect the real iValue above
|
Re: Duplicate Functions Mathias Mamsch - Thu Jun 30 19:26:01 EDT 2011
That is not normal, but I noticed the same. A forward reference before and after the call will crash DOORS with an exception. I guess forward references are not properly implemented. If utterly needed, you could replace the forward declarations by a callback proxy like below. Nice thing about that is, you can change the function at runtime ...
// instead of forward declaring func() use a virtual function
int adFunc = 0;
void call_func_proxy( void cb(int), int x ) { cb(x) }
void set_func (void cb(int) ) { adFunc = (addr_ cb) int }
void func (int x) { if (adFunc != 0) call_func_proxy(addr_ adFunc, x) }
// that function uses the not yet declared func() ...
void myLibraryFunction () { func 10 }
// declare the func we want to use late
void theRealFunc (int var) {
print "This is the implementation of func that I would like to use:" var "\n"
}
// set it as the function we want to use now. May want to change that later.
set_func(theRealFunc)
myLibraryFunction ()
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
I was intrigued by this, since I noted that whilst you can declare a C-style function pointer in DXL, the Interpreter doesn't allow you to call it. So having experimented with your code, I have discovered one small problem: It doesn't work if the routine you want to alias is of the pattern "void(f)(void)". (Obviously after rewriting your example to adapt to the new function type). You get an internal error the moment you try to assign the function address to the integer storage. Presumably this is because the DXL interpreter no-longer understands what is meant by adFunc = (addr_ function) int if the function has no arguments or result. It doesn't know if you meant it to be called or to simply get its address. My suspicion is that it decides to call it, with disastrous results. That said, if you don't mind "throwing away results", you could opt for your function's pattern to be "int(f)(void)". This, for some bizarre reason, does not cause the interpreter to go ape when you do the adFunc = (addr_ function) int part. To experiment with what was going wrong, I extracted the critical part that was causing the interpreter to blow up so I could easily experiment with the function patterns. I provide this below, so you can quickly test what would work and what does not.
int adFunc
void SetF(int (f)(void)) { adFunc=(addr_ f) int }
int Test(void){}
SetF(Test)
The above works.
int adFunc
void SetF(void(f)(int)) { adFunc=(addr_ f) int }
void Test(int){}
SetF(Test)
The above also works.
int adFunc
void SetF(void(f)(void)) { adFunc=(addr_ f) int }
void Test(void){}
SetF(Test)
The above blows up the interpreter! |
Re: Duplicate Functions AlexTidmarsh - Mon Nov 24 18:21:46 EST 2014 I was intrigued by this, since I noted that whilst you can declare a C-style function pointer in DXL, the Interpreter doesn't allow you to call it. So having experimented with your code, I have discovered one small problem: It doesn't work if the routine you want to alias is of the pattern "void(f)(void)". (Obviously after rewriting your example to adapt to the new function type). You get an internal error the moment you try to assign the function address to the integer storage. Presumably this is because the DXL interpreter no-longer understands what is meant by adFunc = (addr_ function) int if the function has no arguments or result. It doesn't know if you meant it to be called or to simply get its address. My suspicion is that it decides to call it, with disastrous results. That said, if you don't mind "throwing away results", you could opt for your function's pattern to be "int(f)(void)". This, for some bizarre reason, does not cause the interpreter to go ape when you do the adFunc = (addr_ function) int part. To experiment with what was going wrong, I extracted the critical part that was causing the interpreter to blow up so I could easily experiment with the function patterns. I provide this below, so you can quickly test what would work and what does not.
int adFunc
void SetF(int (f)(void)) { adFunc=(addr_ f) int }
int Test(void){}
SetF(Test)
The above works.
int adFunc
void SetF(void(f)(int)) { adFunc=(addr_ f) int }
void Test(int){}
SetF(Test)
The above also works.
int adFunc
void SetF(void(f)(void)) { adFunc=(addr_ f) int }
void Test(void){}
SetF(Test)
The above blows up the interpreter! Mighty Magic Hal posted a way to get the address for void functions here: Regards, Mathias |